package com.greens1995.testmap.locate;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.os.ResultReceiver;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

/**
 * Created by Ben on 2017/3/1.
 */
// TODO: 2017/3/2 rx化
public class LocationHelper implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private AddressResultReceiver mResultReceiver;
    private GoogleApiClient mGoogleApiClient;
    private Context mContext;
    private LocationRequest mLocationRequest;
    private LocationListener mLocationListener;

    public interface AsyncLocateListener {
        void onLocate(Location location);

        void onLocateFail();

        void onConnectSuspended(int i);

        void onConnectfail(ConnectionResult connectionResult);
    }
    private AsyncLocateListener asyncLocateListener;
    public void setAsyncLocateListener(AsyncLocateListener asyncLocateListener) {
        this.asyncLocateListener = asyncLocateListener;
    }

    public static final LocationHelper newInstance(Context context) {
        LocationHelper locationHelper = new LocationHelper(context);
        return locationHelper;
    }

    public LocationHelper(Context context) {//TODO: 2017/3/2 地图提供者扩展
        if (!(context instanceof Application)) {
            mContext = context.getApplicationContext();
        }
        mContext = context;
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(mContext)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        mResultReceiver = new AddressResultReceiver(new Handler(context.getMainLooper()));
    }

    public void start() {
        if (!mGoogleApiClient.isConnected()) {
            mGoogleApiClient.connect();
        }
    }

    public void stop() {
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    //
    public void stopLocationUpdates(LocationListener locationListener) {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, locationListener);
    }

    public void onConnected(@Nullable Bundle bundle) {
        if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            asyncLocateListener.onLocate(mLastLocation);
//            Toast.makeText(mContext, "纬度：" + mLastLocation.getLatitude() + "-经度：" + mLastLocation.getLongitude() + mLastLocation.describeContents(), Toast.LENGTH_LONG).show();
        }else {
            asyncLocateListener.onLocateFail();
        }

    }

    @Override
    public void onConnectionSuspended(int i) {
        if (asyncLocateListener != null) {
            asyncLocateListener.onConnectSuspended(i);
        }
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        if (asyncLocateListener != null) {
            asyncLocateListener.onConnectfail(connectionResult);
        }
    }

    public void startLocationUpdates(LocationListener locationListener) {
        if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setInterval(5000); //5 seconds
        mLocationRequest.setFastestInterval(3000); //3 seconds
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationListener);
    }

    public void getAdress(Location location) {
        if (mGoogleApiClient.isConnected() && location != null) {
            startIntentService(location);
        }
    }

    protected void startIntentService(Location location) {
        Intent intent = new Intent(mContext, FetchAddressIntentService.class);
        intent.putExtra(Constants.RECEIVER, mResultReceiver);
        intent.putExtra(Constants.LOCATION_DATA_EXTRA, location);
        mContext.startService(intent);
    }

    private static class AddressResultReceiver extends ResultReceiver {
        public AddressResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {

            // Display the address string
            // or an error message sent from the intent service.
            String mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
//            displayAddressOutput();

            // Show a toast message if an address was found.
            if (resultCode == Constants.SUCCESS_RESULT) {
                Log.i("MapsActivity", "address_found:" + mAddressOutput);
//                showToast();
            }

        }
    }
}
